import { defineStore } from "pinia";
import AxiosManager from "@/axios/axiosManager"
import type { AxiosProgressEvent } from "axios";
import ResUtil from "@/utils/resUtil";
import FileObject from "@/types/response/fileObject";

type RangeType = {
  begin: number;
  end: number;
}

let useFileStore = defineStore("fileStore", () => {
  let instance=AxiosManager.fileAxios;
  function getFileNameByUrl(url:string){
      let index=url.lastIndexOf("@");
      return url.substring(index+1);
  }
  //选择文件上传
  async function selectFile(
    type: "image" | "all" | "mp3" = "all"
  ): Promise<File | null> {
    return new Promise<File>((resolve, reject) => {
      let fileInput = document.createElement("input");
      fileInput.type = "file";
      if (type == "image") fileInput.accept = "image/*";
      else if (type == "mp3") fileInput.accept = "audio/*";
      fileInput.click();
      fileInput.addEventListener("change", () => {
        let file = fileInput.files[0];
        resolve(file);
      });
      fileInput.addEventListener("close", () => {
        resolve(null);
      });
      fileInput.addEventListener("abort", () => {
        resolve(null);
      });
    });
  }
  async function selectFileToUpload(
    type: "image" | "all" | "mp3",
    endFunc: (res: { remoteUrl: string; fileObject: FileObject }) => void
  ) {
    selectFile(type).then(async(f) => {
      if (f != null) {
       let res=await uploadFile(f,{uuid:"",uploadedSize:0})
       endFunc(res)
      } 
    });
  }
  //上传文件
  async function uploadFile(f:File,uploadMessage:{uuid:string,uploadedSize:number}){
    let fileName=f.name;
    let uuid=(await bigFileUploadBegin()).uuid;
    uploadMessage.uuid=uuid;
    uploadMessage.uploadedSize=0;
    let ranges = subDivideRange([{begin:0,end:f.size}]);
    console.log(ranges);
    for (let range of ranges) {
      let b: Blob;
      b =f.slice(range.begin, range.end + 1);
      await uploadPartFile(uploadMessage,range.begin, b).catch((e) => {}); //按照文件一段一段进行传送
    }
    let m = await bigFileUploadEnd(
      uuid,
      fileName,
      f.size
    );
    return m;
  }

  
  //大文件开始传输的准备
  async function bigFileUploadBegin() {
    let res = await instance.post("/bigFileUploadBegin", null);
    return ResUtil.getData<{ uuid: string}>(res);
  }
  //获得将要上传的文件的范围
  async function getReUploadFileRange(
    uuid: string,
    fileSize: number
  ) {
    let res = await instance.get("/getReUploadFileRange", {
      params: {
        uuid,
        fileSize,
      },
    });
    let data = ResUtil.getData<RangeType[]>(res);
    return data;
  }
  //再一次的划分上传区间
  function subDivideRange(ranges: RangeType[]) {
    let newRanges: RangeType[] = [];
    ranges.forEach((range) => {
      let size = range.end - range.begin; //获得当前段的大小
      let perMaxSize = 1024 * 1024 * 5;
      if (size > perMaxSize) {
        let count = Math.floor(size / perMaxSize);
        for (let i = 0; i < count; i++) {
          newRanges.push({
            begin: range.begin + i * perMaxSize,
            end: range.begin + (i + 1) * perMaxSize - 1,
          });
        }
        let endBegin = range.begin + count * perMaxSize;
        if (endBegin <= range.end) {
          newRanges.push({
            begin: endBegin,
            end: range.end,
          });
        }
      }
    });
    return ranges;
  }
  //大文件分片上传
  async function uploadPartFile(
    uploadMsg:{uuid:string,uploadedSize:number},
    beginPos: number,
    partBlob: Blob
  ): Promise<boolean> {
    let res = await instance.post(
       "/uploadPartFile",
      {
        file: partBlob,
        uuid: uploadMsg.uuid,
        beginPos,
      },
      {
        onUploadProgress: (progressEvent: AxiosProgressEvent) => {
          if (progressEvent.loaded) {
            uploadMsg.uploadedSize = beginPos + progressEvent.loaded;
          }
        },
        headers: {
          "Content-Type": "multipart/form-data",
          "encryptBody":false,
          "encryptParams":false
        },
        timeout: 1000 * 60 * 60,
      }
    );
    return ResUtil.isSuccess(res);
  }

  //大文件结束传输,返回文件传输的路径
  async function bigFileUploadEnd(
    uuid: string,
    fileName: string,
    fileSize: number
  ) {
    let res = await instance.post( "/bigFileUploadEnd", null, {
      params: {
        uuid,
        fileName,
        fileSize,
      },
    });
    return ResUtil.getData<{
      remoteUrl: string;
      fileObject: FileObject;
    }>(res);
  }
  async function download(uri:string){
    
      let a = document.createElement('a')
      a.download = getFileNameByUrl(uri);
      a.style.display = 'none'
      a.href = encodeURI(uri);
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
  }
  //#endregion
  return {
    selectFile,
    selectFileToUpload,
    uploadFile,
    download,
    getFileNameByUrl
  };
})
export default useFileStore;
